#ifndef POSITIONWIDGET_H
#define POSITIONWIDGET_H

#include <QDialog>
#include <QWidget>
#include <QResource>
#include <QGraphicsScene>
#include <QGraphicsPixmapItem>

#include "note.h"
#include "position.h"
#include "conversions.h"
#include "instrument.h"

#include "widgets/instrumentinfo.h"

#include "xmlpositionparser.h"

namespace Ui {
class PositionWidget;
}

class PositionWidget : public QWidget
{
    Q_OBJECT
    
public:
    explicit PositionWidget(QWidget *parent = 0);
    ~PositionWidget();
    
private:
    Ui::PositionWidget *ui;

    // Init stuff
    void buildWidgets(void);
    void setupConnections(void);
    void setupWidgets(void);

    // Rebuild combo tree according to new input
    void rebuildComboTree(QString className = "", QString instrumentName = "", QString typeName = "", QString tonalityName = "");

    // Position Note and Everithing update and display
    void updateInstrument(void); // update position, calls updateNote
    void updatePosition(void); // update position, calls updateFreq
    void updateNote(void); // update note, calls updatePosition and updateFreq
    void updateFreq(void); // update note, calls updatePosition
    void updateAll(void) { updateInstrument(); }

    // Position scnene handler
    void displayPosition(int index = 0); // Display position number i
    void clearPosition(void); // Clear position view
    void displayPositionImg(Position position = Position()); // Display position image

    // Note scene
    void displayNote(int index = 0); // Display position number indexndex
    void clearNote(void); // Clear position view
    void displayNoteImg(Note note = Note()); // Display note image

    // Member acces
    // Current position getPosition, handle empty position
    Position currentPosition(void) { if (!pos_by_note_list.isEmpty()) return pos_by_note_list.at(current_pos_index); else return Position(); }
    Position currentNote(void) { if (!note_by_pos_list.isEmpty()) return note_by_pos_list.at(current_note_index); else return Position(); }

    // Set Combo indexes
    void setPitchComboIndex(int i = 0, bool rel = false);
    void setAltComboIndex(int i = 0, bool rel = false);
    void setOctComboIndex(int i = 0, bool rel = false);

    // PRIVATE MEMBERS
    QDialog * diag;
    InstrumentInfo * inswid;

    // XmlHandler
    XmlPositionParser xmlParser;

    // General members
    Instrument instrument;
    Clef current_clef;

    // Members for SearchByNote
    Note current_note;
    QList< Position > pos_by_note_list;
    int current_note_index;
    bool interpret_as_real_note;
    bool display_real_note_SBN;

    // Members for SearchByPosition
    QList< Position > note_by_pos_list;
    int current_pos_index;
    bool display_real_note_SBP;

public slots:
    void onNoteChanged(void);
    void onClefChanged(void);
    void onInstrumentClassChanged(void);
    void onInstrumentNameChanged(void);
    void onInstrumentTypeChanged(void);
    void onInstrumentTonalityChanged(void);

    void updateSearchByNote(void) { updateNote(); }
    void updateSearchByPosition(void);

    void nextPos(void) { displayPosition(++current_pos_index); }
    void prevPos(void) { displayPosition(--current_pos_index); }
    void nextNote(void) { displayNote(++current_note_index); }
    void prevNote(void) { displayNote(--current_note_index); }

    void prevPitch() { setPitchComboIndex(-1, true); }
    void nextPitch() { setPitchComboIndex(1, true); }
    void prevAlt() { setAltComboIndex(-1, true); }
    void nextAlt() { setAltComboIndex(1, true); }
    void prevOct() { setOctComboIndex(-1, true); }
    void nextOct() { setOctComboIndex(1, true); }

    void setDisplayRealSBP(bool b) { display_real_note_SBP = b; updateSearchByPosition(); }
    void setDisplayRealSBN(bool b) { display_real_note_SBN = b; updateSearchByNote(); }
    void setInterpretAsReal(bool b) { interpret_as_real_note = b; updateSearchByNote(); }

    // Instrument window
    void onInstrumentButtonClicked();
};

#endif // POSITIONWIDGET_H
